/**
 * @file    WebEventHandler.cpp
 * @brief   
 * @date    2005-03-15 15:55:23
 * @author  GengYong (gengyong@gmail.com)
 *
 */

#include <exdispid.h>
#include <cassert>
#include "WebEventHandler.h"


using namespace xessage_private;

WebEventHandler::WebEventHandler(WebWindowImpl * app):m_appImpl(app), m_refCount(1)
{
	return;
}

WebEventHandler::~WebEventHandler()
{
	return;
}

HRESULT STDMETHODCALLTYPE WebEventHandler::QueryInterface(REFIID riid, LPVOID * ppvObject)
{
	if (ppvObject == NULL) return E_POINTER;

	if ((riid == IID_IUnknown) || (riid == IID_IDispatch))
	{
		this->AddRef();
		*ppvObject = this;
	}
	else
	{
		*ppvObject = 0;
		return E_NOINTERFACE;
	}
	return S_OK;
}

ULONG STDMETHODCALLTYPE WebEventHandler::AddRef()
{
	return InterlockedIncrement(&m_refCount);
}

ULONG STDMETHODCALLTYPE WebEventHandler::Release()
{
	LONG result = InterlockedDecrement(&m_refCount);
	assert(result >= 0);
	if (result == 0)
	{
		delete this;
	}
	return (ULONG)(result);
}

HRESULT STDMETHODCALLTYPE WebEventHandler::GetTypeInfoCount(UINT *pctinfo)
{
	return E_NOTIMPL;;
}

HRESULT STDMETHODCALLTYPE WebEventHandler::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
{
	return E_NOTIMPL;;
}


HRESULT STDMETHODCALLTYPE WebEventHandler::GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
{
	return E_NOTIMPL;;
}


HRESULT STDMETHODCALLTYPE WebEventHandler::Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult, EXCEPINFO* pexcepinfo, UINT* puArgErr)
{
	if(memcmp(&riid, &IID_NULL, sizeof(GUID)) != 0)  return DISP_E_UNKNOWNINTERFACE;

	HRESULT hres = S_OK;
	UINT	aerr = 0;
	
	if (puArgErr == NULL) puArgErr = &aerr;

	switch (dispidMember)
	{	
	case DISPID_STATUSTEXTCHANGE:
		{
			VARIANTARG Argument0;
			VariantInit(&Argument0);
			if ((hres = DispGetParam(pdispparams, 0, VT_BSTR, &Argument0, puArgErr)) == S_OK)
			{
				xessage::IEventHandler * handler = m_appImpl->GetEventHandler();
				if (handler) handler->StatusTextChange(V_BSTR(&Argument0));
			}
		}
		break;
	case DISPID_DOWNLOADCOMPLETE:
		{
			xessage::IEventHandler * handler = m_appImpl->GetEventHandler();
			if (handler) handler->DownloadComplete();
		}
		break;
	case DISPID_COMMANDSTATECHANGE:
		{
			VARIANTARG Argument0, Argument1;
			VariantInit(&Argument0); VariantInit(&Argument1);
			if ((hres = DispGetParam(pdispparams, 0, VT_I4, &Argument0, puArgErr)) == S_OK)
			if ((hres = DispGetParam(pdispparams, 1, VT_BOOL, &Argument1, puArgErr)) == S_OK)
			{
				xessage::IEventHandler * handler = m_appImpl->GetEventHandler();
				if (handler) handler->CommandStateChange(V_I4(&Argument0), V_BOOL(&Argument1));
			}
		}
		break;
	case DISPID_DOWNLOADBEGIN:
		{
			xessage::IEventHandler * handler = m_appImpl->GetEventHandler();
			if (handler) handler->DownloadBegin();
		}
		break;
	case DISPID_PROGRESSCHANGE:
		{
			VARIANTARG Argument0, Argument1;
			VariantInit(&Argument0); VariantInit(&Argument1);
			if ((hres = DispGetParam(pdispparams, 0, VT_I4, &Argument0, puArgErr)) == S_OK)
			if ((hres = DispGetParam(pdispparams, 1, VT_I4, &Argument1, puArgErr)) == S_OK)
			{
				xessage::IEventHandler * handler = m_appImpl->GetEventHandler();
				if (handler) handler->ProgressChange(V_I4(&Argument0), V_I4(&Argument1));
			}
		}
		break;
	case DISPID_PROPERTYCHANGE:
		{
			VARIANTARG Argument0;
			VariantInit(&Argument0);
			if ((hres = DispGetParam(pdispparams, 0, VT_BSTR, &Argument0, puArgErr)) == S_OK)
			{
				xessage::IEventHandler * handler = m_appImpl->GetEventHandler();
				if (handler) handler->PropertyChange(V_BSTR(&Argument0));
			}
		}
		break;
	case DISPID_TITLECHANGE:
		{
			VARIANTARG Argument0;
			VariantInit(&Argument0);
			if ((hres = DispGetParam(pdispparams, 0, VT_BSTR, &Argument0, puArgErr)) == S_OK)
			{
				xessage::IEventHandler * handler = m_appImpl->GetEventHandler();
				if (handler) handler->TitleChange(V_BSTR(&Argument0));
			}
		}
		break;
	case DISPID_PRINTTEMPLATEINSTANTIATION:
		{
			VARIANTARG Argument0;
			VariantInit(&Argument0);
			if ((hres = DispGetParam(pdispparams, 0, VT_DISPATCH, &Argument0, puArgErr)) == S_OK)
			{
				xessage::IEventHandler * handler = m_appImpl->GetEventHandler();
				if (handler) handler->PrintTemplateInstantiation(V_DISPATCH(&Argument0));
			}
		}
		break;
	case DISPID_PRINTTEMPLATETEARDOWN:
		{
			VARIANTARG Argument0;
			VariantInit(&Argument0);
			if ((hres = DispGetParam(pdispparams, 0, VT_DISPATCH, &Argument0, puArgErr)) == S_OK)
			{
				xessage::IEventHandler * handler = m_appImpl->GetEventHandler();
				if (handler) handler->PrintTemplateTeardown(V_DISPATCH(&Argument0));
			}
		}
		break;
	case DISPID_BEFORENAVIGATE2:
		{
			VARIANTARG Argument0, Argument1, Argument3,  Argument5, Argument6;
			VariantInit(&Argument0); VariantInit(&Argument1); VariantInit(&Argument3); 
			VariantInit(&Argument5); VariantInit(&Argument6);
			if ((hres = DispGetParam(pdispparams, 0, VT_DISPATCH, &Argument0, puArgErr)) == S_OK)
			if ((hres = DispGetParam(pdispparams, 1, VT_BSTR, &Argument1, puArgErr)) == S_OK)
			if ((hres = DispGetParam(pdispparams, 3, VT_BSTR, &Argument3, puArgErr)) == S_OK)
			if ((hres = DispGetParam(pdispparams, 5, VT_BSTR, &Argument5, puArgErr)) == S_OK)
			if ((hres = DispGetParam(pdispparams, 6, VT_BOOL, &Argument6, puArgErr)) == S_OK)
			{
				xessage::IEventHandler * handler = m_appImpl->GetEventHandler();
				if (handler) handler->BeforeNavigate(V_DISPATCH(&Argument0), V_BSTR(&Argument1), V_BSTR(&Argument3), V_BSTR(&Argument5), V_BOOLREF(&Argument6));
			}
		}
		break;
	case DISPID_NEWWINDOW2:
		{
			VARIANTARG Argument0, Argument1;
			VariantInit(&Argument0); VariantInit(&Argument1);
			if ((hres = DispGetParam(pdispparams, 0, VT_DISPATCH, &Argument0, puArgErr)) == S_OK)
			if ((hres = DispGetParam(pdispparams, 1, VT_BOOL, &Argument1, puArgErr)) == S_OK)
			{
				xessage::IEventHandler * handler = m_appImpl->GetEventHandler();
				if (handler) handler->NewWindow(V_DISPATCHREF(&Argument0), V_BOOLREF(&Argument1));
			}
		}
		break;
	case DISPID_NAVIGATECOMPLETE2:
		{
			VARIANTARG Argument0, Argument1;
			VariantInit(&Argument0); VariantInit(&Argument1);
			if ((hres = DispGetParam(pdispparams, 0, VT_DISPATCH, &Argument0, puArgErr)) == S_OK)
			if ((hres = DispGetParam(pdispparams, 1, VT_BSTR, &Argument1, puArgErr)) == S_OK)
			{
				xessage::IEventHandler * handler = m_appImpl->GetEventHandler();
				if (handler) handler->NavigateComplete(V_DISPATCH(&Argument0), V_BSTR(&Argument1));
			}
		}
		break;
	case DISPID_ONVISIBLE:
		{
			VARIANTARG Argument0;
			VariantInit(&Argument0);
			if ((hres = DispGetParam(pdispparams, 0, VT_BOOL, &Argument0, puArgErr)) == S_OK)
			{
				xessage::IEventHandler * handler = m_appImpl->GetEventHandler();
				if (handler) handler->OnVisible(V_BOOL(&Argument0));
			}
		}
		break;
	case DISPID_DOCUMENTCOMPLETE:
		{
			VARIANTARG Argument0, Argument1;
			VariantInit(&Argument0); VariantInit(&Argument1);
			if ((hres = DispGetParam(pdispparams, 0, VT_DISPATCH, &Argument0, puArgErr)) == S_OK)
			if ((hres = DispGetParam(pdispparams, 1, VT_BSTR, &Argument1, puArgErr)) == S_OK)
			{
				xessage::IEventHandler * handler = m_appImpl->GetEventHandler();
				if (handler) handler->DocumentComplete(V_DISPATCH(&Argument0), V_BSTR(&Argument1));
			}
		}
		break;
	case DISPID_WINDOWSETRESIZABLE:
		{
			VARIANTARG Argument0;
			VariantInit(&Argument0);
			if ((hres = DispGetParam(pdispparams, 0, VT_BOOL, &Argument0, puArgErr)) == S_OK)
			{
				xessage::IEventHandler * handler = m_appImpl->GetEventHandler();
				if (handler) handler->WindowSetResizable(V_BOOL(&Argument0));
			}
		}
		break;
	case DISPID_WINDOWCLOSING:
		{
			VARIANTARG Argument0, Argument1;
			VariantInit(&Argument0); VariantInit(&Argument1);
			if ((hres = DispGetParam(pdispparams, 0, VT_BOOL, &Argument0, puArgErr)) == S_OK)
			if ((hres = DispGetParam(pdispparams, 1, VT_BOOL, &Argument1, puArgErr)) == S_OK)
			{
				xessage::IEventHandler * handler = m_appImpl->GetEventHandler();
				if (handler) handler->WindowClosing(V_BOOL(&Argument0), V_BOOLREF(&Argument1));
			}
		}
		break;
	case DISPID_WINDOWSETLEFT:
		{
			VARIANTARG Argument0;
			VariantInit(&Argument0);
			if ((hres = DispGetParam(pdispparams, 0, VT_I4, &Argument0, puArgErr)) == S_OK)
			{
				xessage::IEventHandler * handler = m_appImpl->GetEventHandler();
				if (handler) handler->WindowSetLeft(V_I4(&Argument0));
			}
		}
		break;
	case DISPID_WINDOWSETTOP:
		{
			VARIANTARG Argument0;
			VariantInit(&Argument0);
			if ((hres = DispGetParam(pdispparams, 0, VT_I4, &Argument0, puArgErr)) == S_OK)
			{
				xessage::IEventHandler * handler = m_appImpl->GetEventHandler();
				if (handler) handler->WindowSetTop(V_I4(&Argument0));
			}
		}
		break;
	case DISPID_WINDOWSETWIDTH:
		{
			VARIANTARG Argument0;
			VariantInit(&Argument0);
			if ((hres = DispGetParam(pdispparams, 0, VT_I4, &Argument0, puArgErr)) == S_OK)
			{
				xessage::IEventHandler * handler = m_appImpl->GetEventHandler();
				if (handler) handler->WindowSetWidth(V_I4(&Argument0));
			}
		}
		break;
	case DISPID_WINDOWSETHEIGHT:
		{
			VARIANTARG Argument0;
			VariantInit(&Argument0);
			if ((hres = DispGetParam(pdispparams, 0, VT_I4, &Argument0, puArgErr)) == S_OK)
			{
				xessage::IEventHandler * handler = m_appImpl->GetEventHandler();
				if (handler) handler->WindowSetHeight(V_I4(&Argument0));
			}
		}
		break;
	case DISPID_CLIENTTOHOSTWINDOW:
		{
			VARIANTARG Argument0, Argument1;
			VariantInit(&Argument0); VariantInit(&Argument1);
			if ((hres = DispGetParam(pdispparams, 0, VT_I4, &Argument0, puArgErr)) == S_OK)
			if ((hres = DispGetParam(pdispparams, 1, VT_I4, &Argument1, puArgErr)) == S_OK)
			{
				xessage::IEventHandler * handler = m_appImpl->GetEventHandler();
				if (handler) handler->ClientToHostWindow(V_I4REF(&Argument0), V_I4REF(&Argument1));
			}
		}
		break;
	case DISPID_SETSECURELOCKICON:
		{
			VARIANTARG Argument0;
			VariantInit(&Argument0);
			if ((hres = DispGetParam(pdispparams, 0, VT_I4, &Argument0, puArgErr)) == S_OK)
			{
				xessage::IEventHandler * handler = m_appImpl->GetEventHandler();
				if (handler) handler->SetSecureLockIcon(V_I4(&Argument0));
			}
		}
		break;
	case DISPID_FILEDOWNLOAD:
		{
			VARIANTARG	Argument0;
			VariantInit(&Argument0);
			if ((hres = DispGetParam(pdispparams, 0, VT_BOOL, &Argument0, puArgErr)) == S_OK)
			{
				xessage::IEventHandler * handler = m_appImpl->GetEventHandler();
				if (handler) handler->FileDownload(V_BOOLREF(&Argument0));
			}
		}
		break;
	case DISPID_NAVIGATEERROR:
		{
			VARIANTARG Argument0, Argument1, Argument2, Argument3, Argument4;
			VariantInit(&Argument0); VariantInit(&Argument1); VariantInit(&Argument2);
			VariantInit(&Argument3); VariantInit(&Argument4);
			if ((hres = DispGetParam(pdispparams, 0, VT_DISPATCH, &Argument0, puArgErr)) == S_OK)
			if ((hres = DispGetParam(pdispparams, 1, VT_BSTR, &Argument1, puArgErr)) == S_OK)
			if ((hres = DispGetParam(pdispparams, 2, VT_BSTR, &Argument2, puArgErr)) == S_OK)
			if ((hres = DispGetParam(pdispparams, 3, VT_I4, &Argument3, puArgErr)) == S_OK)
			if ((hres = DispGetParam(pdispparams, 4, VT_BOOL, &Argument4, puArgErr)) == S_OK)
			{
				xessage::IEventHandler * handler = m_appImpl->GetEventHandler();
				if (handler) handler->NavigateError(V_DISPATCH(&Argument0), V_BSTR(&Argument1), V_BSTR(&Argument2), V_I4(&Argument3), V_BOOLREF(&Argument4));
			}
		}
		break;
	case DISPID_PRIVACYIMPACTEDSTATECHANGE:
		{
			VARIANTARG Argument0;
			VariantInit(&Argument0);
			if ((hres = DispGetParam(pdispparams, 0, VT_BOOL, &Argument0, puArgErr)) == S_OK)
			{
				xessage::IEventHandler * handler = m_appImpl->GetEventHandler();
				if (handler) handler->PrivacyImpactedStateChange(V_BOOL(&Argument0));
			}
		}
		break;
	default:
		hres = DISP_E_MEMBERNOTFOUND;
		break;
	}
	return hres;
}

